package com.quectel.cms.controller.dept;


import cn.hutool.core.lang.func.LambdaUtil;
import com.quectel.cms.controller.BaseController;
import com.quectel.cms.vo.dept.DeptLazyNode;
import com.quectel.constant.global.SystemConstants;
import com.quectel.constant.global.TreeData;
import com.quectel.constant.global.annotation.RequirePermissions;
import com.quectel.core.module.dept.dto.DeptDto;
import com.quectel.core.module.dept.dto.DeptPersonDto;
import com.quectel.core.module.dept.service.DeptPersonService;
import com.quectel.core.module.dept.service.DeptService;
import com.quectel.core.module.village.dto.VillageDto;
import com.quectel.core.module.village.service.VillageService;
import com.quectel.util.common.Page;
import com.quectel.util.common.Request;
import com.quectel.util.common.Response;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author caolu
 * @email louis.cao@quectel.com
 * @date 2022/03/24 10:07
 */
@RestController
@RequestMapping("dept")
@Tag(name = "DeptController", description = "部门相关api")
public class DeptController extends BaseController {

    @DubboReference
    private DeptService deptService;
    @DubboReference
    private DeptPersonService deptPersonService;
    @DubboReference
    private VillageService villageService;

    @GetMapping("loadTreeNode")
    @Operation(summary = "根据条件对社区系系节点列表加载")
    public Response<List<DeptLazyNode>> loadTreeNode(
            @Parameter(description = "社区id") @RequestParam Long villageId,
            @Parameter(description = "部门节点id 不传默认加载第一层") @RequestParam(required = false) Long deptId
    ) {
        Map<String, Object> params = new HashMap<>();
        params.put(SystemConstants.SORT_ORDER_BY_KEY, LambdaUtil.getFieldName(DeptDto::getSort));
        params.put(SystemConstants.SORT_ORDER_RULE_KEY, SystemConstants.SORT_ORDER_RULE_DESC);
        params.put(LambdaUtil.getFieldName(DeptDto::getVillageId), villageId);
        super.fillAuthorityData(params);
        if (deptId == null) {
            params.put(LambdaUtil.getFieldName(DeptDto::getLevel), SystemConstants.TREE_DEFAULT_LEVEL);
        } else {
            params.put(LambdaUtil.getFieldName(DeptDto::getParentId), deptId);
        }

        List<DeptDto> deptDtos = deptService.queryList(params);
        List<DeptLazyNode> result = deptDtos.stream()
                .map(o -> new DeptLazyNode(String.valueOf(o.getId()), o.getName()))
                .collect(Collectors.toList());
        return Response.<List<DeptLazyNode>>ok().wrap(result);
    }

    /**
     * 列表
     */
    @GetMapping("treeData")
    @RequirePermissions(values = "dept:treeData")
    @Operation(summary = "查询部门菜单列表")
    public Response<List<TreeData>> treeData(
    ) {
        //查询列表数据
        Request request = Request.configParamsNotPage(Request.parseParams(httpServletRequest));
        super.fillAuthorityData(request.getParams());

        List<VillageDto> villageDtoList = villageService.queryList(request.getParams());

        List<DeptDto> depts = deptService.queryList(request.getParams());

        List<TreeData> simpleTree = new ArrayList<>();

        simpleTree.addAll(
                villageDtoList.stream().map(v -> {
                    TreeData treeData = new TreeData();
                    treeData.setId(String.valueOf(v.getId()));
                    treeData.setName(v.getName());
                    treeData.setParentId(SystemConstants.TREE_DEFAULT_PARENT_ID.toString());
                    treeData.setLevel(SystemConstants.ZERO);
                    treeData.setSort(SystemConstants.ZERO.intValue());
                    treeData.setOpen(SystemConstants.YES);

                    treeData.setExtData(String.valueOf(v.getId()));
                    return treeData;
                }).collect(Collectors.toList())
        );
        simpleTree.addAll(
                depts.stream().map(v -> {
                    TreeData treeData = new TreeData();
                    treeData.setId(String.valueOf(v.getId()));
                    treeData.setName(v.getName());
                    treeData.setParentId(String.valueOf(v.getParentId()));
                    treeData.setLevel(v.getLevel());
                    treeData.setSort(v.getSort());
                    treeData.setOpen(SystemConstants.YES);

                    treeData.setExtData(String.valueOf(v.getVillageId()));
                    return treeData;
                }).collect(Collectors.toList())
        );
        if (simpleTree != null) {
            simpleTree.sort(new Comparator<TreeData>() {
                @Override
                public int compare(TreeData o1, TreeData o2) {
                    if (o1.getSort() != null && o2.getSort() != null) {
                        return o1.getSort() - o2.getSort();
                    }
                    return 0;
                }
            });
        }
        return Response.<List<TreeData>>ok().wrap(TreeData.simpleToChildren(simpleTree, SystemConstants.TREE_DEFAULT_PARENT_ID.toString()));
    }

    /**
     * 列表
     */
    @GetMapping("queryByVillageId")
    @Operation(summary = "根据小区id查询所有部门列表")
    public Response<List<DeptDto>> list(
            @RequestParam Long villageId
    ) {
        Map<String, Object> params = new HashMap<>();
        params.put(LambdaUtil.getFieldName(DeptDto::getVillageId), String.valueOf(villageId));

        List<DeptDto> list = deptService.queryList(params);

        return Response.<List<DeptDto>>ok().wrap(list);
    }

    /**
     * 列表
     */
    @GetMapping("list")
    @RequirePermissions(values = "dept:list")
    @Operation(summary = "部门的分页查询列表")
    public Response<Page<DeptDto>> list(
            @Parameter(description = "从1开始的页码数") @RequestParam Integer pageNo,
            @Parameter(description = "每页多少条") @RequestParam Integer pageSize
    ) {
        //查询列表数据
        Request request = Request.configParams(Request.parseParams(httpServletRequest));

        super.fillAuthorityData(request.getParams());
        int total = deptService.queryTotal(request.getParams());

        List<DeptDto> list = null;
        if (total > 0) {
            list = deptService.queryList(request.getParams());
        } else {
            list = new ArrayList<>();
        }

        Page<DeptDto> page = new Page<>(request.getPageNo(), request.getPageSize(), total, list);
        return Response.<Page<DeptDto>>ok().wrap(page);
    }


    /**
     * 编辑反显查询
     */
    @GetMapping("infoForEdit/{id}")
    @RequirePermissions(values = "dept:edit")
    @Operation(summary = "查询单条部门记录")
    public Response<DeptDto> infoForEdit(@PathVariable("id") Long id) {

        Map<String, Object> params = new HashMap<>();
        super.fillAuthorityData(params);
        params.put(SystemConstants.ENTITY_ID_FLAG, String.valueOf(id));
        if (deptService.queryTotal(params) <= 0) {
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }

        DeptDto deptDto = deptService.selectById(id);

        return Response.<DeptDto>ok().wrap((deptDto));
    }

    /**
     * 信息
     */
    @GetMapping("info/{id}")
    @RequirePermissions(values = "dept:info")
    @Operation(summary = "查询单条部门记录")
    public Response<DeptDto> info(@PathVariable("id") Long id) {

        Map<String, Object> params = new HashMap<>();
        super.fillAuthorityData(params);
        params.put(SystemConstants.ENTITY_ID_FLAG, String.valueOf(id));
        if (deptService.queryTotal(params) <= 0) {
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }

        DeptDto deptDto = deptService.selectById(id);

        if (deptDto != null) {
            VillageDto villageDto = villageService.selectById(deptDto.getVillageId());
            deptDto.setVillageDto(villageDto);
        }

        return Response.<DeptDto>ok().wrap(deptDto);
    }

    /**
     * 保存
     */
    @PostMapping("save")
    @RequirePermissions(values = "dept:edit")
    @Operation(summary = "保存单条部门记录")
    public Response<Object> save(@RequestBody @Validated DeptDto deptDto) {


        if (Objects.equals(deptDto.getLevel(), (byte) (SystemConstants.ZERO + 1))) {
            //第一层级 社区id就是父级
            deptDto.setVillageId(deptDto.getParentId());
        } else {
            //其他情况则是父亲的社区id
            DeptDto parentDto = deptService.selectById(deptDto.getParentId());
            if (parentDto != null) {
                deptDto.setVillageId(parentDto.getVillageId());
            }
        }

        DeptDto objByCode = deptService.selectByCode(deptDto.getVillageId(), deptDto.getCode());
        if (objByCode != null) {
            return Response.error("同一社区部门编码不能重复");
        }
        DeptDto objByName = deptService.selectByCode(deptDto.getVillageId(), deptDto.getName());
        if (objByName != null) {
            return Response.error("同一社区部门名称不能重复");
        }

        //填充基础数据
        fillSaveCommonData(deptDto);


        deptService.saveOrUpdate(deptDto);

        return Response.ok();
    }

    /**
     * 修改
     */
    @PostMapping("update")
    @RequirePermissions(values = "dept:edit")
    @Operation(summary = "修改单条部门记录")
    public Response<Object> update(@RequestBody @Validated DeptDto deptDto) {

        Map<String, Object> params = new HashMap<>();
        super.fillAuthorityData(params);
        params.put(SystemConstants.ENTITY_ID_FLAG, String.valueOf(deptDto.getId()));
        if (deptService.queryTotal(params) <= 0) {
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }

        if (Objects.equals(deptDto.getLevel(), (byte) (SystemConstants.ZERO + 1))) {
            //第一层级 社区id就是父级
            deptDto.setVillageId(deptDto.getParentId());
        } else {
            //其他情况则是父亲的社区id
            DeptDto parentDto = deptService.selectById(deptDto.getParentId());
            if (parentDto != null) {
                deptDto.setVillageId(parentDto.getVillageId());
            }
        }

        DeptDto objByCode = deptService.selectByCode(deptDto.getVillageId(), deptDto.getCode());
        if (objByCode != null && !Objects.equals(deptDto.getId(), objByCode.getId())) {

            return Response.error("同一社区部门编码不能重复");
        }
        DeptDto objByName = deptService.selectByCode(deptDto.getVillageId(), deptDto.getName());
        if (objByName != null && !Objects.equals(deptDto.getId(), objByName.getId())) {
            return Response.error("同一社区部门名称不能重复");
        }

        //填充基础数据
        fillEditCommonData(deptDto);

        deptService.saveOrUpdate(deptDto);

        return Response.ok();
    }

    /**
     * 删除
     */
    @PostMapping("delete")
    @RequirePermissions(values = "dept:delete")
    @Operation(summary = "批量删除存在的部门记录")
    public Response<Object> delete(@RequestBody Long[] ids) {

        Map<String, Object> params = new HashMap<>();
        super.fillAuthorityData(params);

        for (Long id : ids) {

            params.remove(SystemConstants.ENTITY_ID_FLAG);
            params.put(SystemConstants.ENTITY_ID_FLAG, String.valueOf(id));

            if (deptService.queryTotal(params) <= 0) {
                return Response.error(SystemConstants.ILLEGAL_MSG);
            }

            params.clear();
            params.put(LambdaUtil.getFieldName(DeptDto::getParentId), String.valueOf(id));
            int childrenCount = deptService.queryTotal(params);
            if (childrenCount > 0) {
                return Response.error("改机构下有子机构无法删除");
            }
            params.clear();
            params.put(LambdaUtil.getFieldName(DeptPersonDto::getDeptId), String.valueOf(id));

            int personCount = deptPersonService.queryTotal(params);
            if (personCount > 0) {
                return Response.error("该机构下存在人员无法删除");
            }

        }

        deptService.deleteBatch(ids);

        return Response.ok();
    }

    /**
     * 不带分页列表列表
     */
    @GetMapping("nonPagedlist")
    @RequirePermissions(values = "dept:list")
    @Operation(summary = "不带分页列表列表")
    public Response<List<DeptDto>> nonPagedlist() {
        //查询列表数据
        Request request = Request.configParams(Request.parseParams(httpServletRequest));

        super.fillAuthorityData(request.getParams());
        int total = deptService.queryTotal(request.getParams());

        List<DeptDto> list = null;
        if (total > 0) {
            list = deptService.queryList(request.getParams());
        } else {
            list = new ArrayList<>();
        }

        return Response.<List<DeptDto>>ok().wrap(list);
    }
}
